#include "Player.h"
#include "Enemy.h"
#include <iostream>
//This code defines a `Player` class derived from `Character`. It manages a player's experience, level, and inventory. The `gainExperience` method allows the player to earn experience and checks for level - ups. When leveling up, attributes are boosted. The `attack` method simulates an attack on a target, calculates damage, and rewards experience if the target is an enemy. It also overloads `+` and `+=` operators for convenience.
Player::Player(const std::string& name, const std::string& desc)
    : Character(name, desc, 30, 8, 4), experience(0), level(1) {
}

int Player::getExperience() const {
    return experience;
}

int Player::getLevel() const {
    return level;
}

void Player::gainExperience(int exp) {
    if (exp > 0) {
        experience += exp;
        std::cout << "You gained " << exp << " experience points!" << std::endl;
        
        // Check if level up
        while (checkLevelUp()) { 
            std::cout << "Congratulations! You leveled up! You are now level " << level << "." << std::endl;
        }
    }
}

bool Player::checkLevelUp() {
    // Reduced experience needed for level up: 50 times current level (was 100 times)
    int expNeeded = level * 50;
    
    if (experience >= expNeeded) {
        experience -= expNeeded;
        level++;
        
        // Increase attributes through temporary item when leveling up
        Item* levelUpBonus = new Item("Level Up Bonus", "Ability boost gained from leveling up", 5, 2, 1);
        this->addToInventory(levelUpBonus);
        
        return true;
    }
    
    return false;
}

bool Player::attack(ICharacter& target) {
    std::cout << "You attacked " << target.getName() << "!" << std::endl;
    
    // Record enemy's health before attack
    unsigned targetHealthBefore = target.getHealth();
    
    // Execute attack
    bool isAliveAfterAttack = Character::attack(target);
    
    // Calculate actual damage
    unsigned damageDealt = 0;
    if (getAttack() > target.getDefense()) {
        damageDealt = getAttack() - target.getDefense();
        
        // Ensure it doesn't exceed the enemy's original health
        if (damageDealt > targetHealthBefore) {
            damageDealt = targetHealthBefore;
        }
        
        std::cout << "You dealt " << damageDealt << " damage!" << std::endl;
        
        // If enemy is dead
        if (!isAliveAfterAttack) {
            std::cout << "You defeated " << target.getName() << " with a fatal blow!" << std::endl;
            
            // If target is an enemy, gain experience
            Enemy* enemy = dynamic_cast<Enemy*>(&target);
            if (enemy) {
                gainExperience(enemy->getExperienceReward());
            }
        } else {
            // Enemy is still alive, display remaining health
            std::cout << target.getName() << " HP: " << target.getHealth() << "/" << target.getMaxHealth() << std::endl;
        }
    } else {
        // Attack not sufficient to break through defense
        std::cout << "Your attack was completely blocked by " << target.getName() << "'s defense!" << std::endl;
    }
    
    return isAliveAfterAttack;
}

void Player::display() const {
    Character::display();
    std::cout << "Level: " << level << std::endl;
    std::cout << "Experience: " << experience << "/" << (level * 50) << std::endl;
}

// Implementation of operator overloading at the end of file
bool Player::operator+(ICharacter& target) {
    // Use + operator to represent attack
    return this->attack(target);
}

Player& Player::operator+=(Item* item) {
    // Use += operator to represent adding item to inventory
    this->addToInventory(item);
    return *this;
} 